home *** CD-ROM | disk | FTP | other *** search
- package sub_arctic.lib;
-
-
- import sub_arctic.output.drawable;
- import sub_arctic.output.style;
- import sub_arctic.output.style_manager;
-
- import java.awt.Font;
- import java.awt.FontMetrics;
- import java.awt.Color;
- import java.util.Vector;
-
- /**
- * Text edit area displayer. This class displays a multi-line area of text
- * with a selection point or area in a fashion suitable for use by a small
- * text editor interactor. Selection positions are given as a line number
- * and position with a line. Positions with a line refer to the
- * spaces before the characters (numbered from 0). So for example a
- * selection from line 0, character 0 to line 0, character 0 places
- * the cursor before the first character being displayed, while a
- * selection from line 1 character 1 to line 2 character 2 selects from
- * the second character of the second line, up to and including the second
- * character of the third line.
- *
- * @author Scott Hudson
- */
- public class text_display extends base_interactor {
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Extra vertical spacing at top and bottom of text */
- protected int _v_spacing = 3;
-
- /**
- * Extra vertical spacing at top and bottom of text.
- * @return int the vertical spacing value.
- */
- public int v_spacing() {return _v_spacing;}
-
- /**
- * Set extra vertical spacing at top and bottom of text.
- * @param int v the new spacing value.
- */
- public void set_v_spacing(int v)
- {
- if (v != _v_spacing)
- {
- _v_spacing = v;
- damage_self();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Extra horizontal spacing at left and right of text */
- protected int _h_spacing = 3;
-
- /**
- * Extra horizontal spacing at left and right of text.
- * @return int the horizontal spacing value.
- */
- public int h_spacing() {return _h_spacing;}
-
- /**
- * Set extra horizontal spacing at left and right of text.
- * @param int v the new spacing value.
- */
- public void set_h_spacing(int v)
- {
- if (v != _h_spacing)
- {
- _h_spacing = v;
- damage_self();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Cached font metrics object for the current font */
- protected FontMetrics _metric;
-
- /** Font that interactor displays in */
- protected Font _font;
-
- // note: later we might just store the metrics object, since we can get the
- // front from that
-
- /**
- * Font that interactor displays in
- * @return Font the font this interactor is using; will return the system's
- * default font if you don't specify a font
- */
- public Font font() {return _font;}
-
- /**
- * Set font that interactor displays in
- * @param Font fnt the font to use for this interactor (use null to get the
- * system's default font
- */
- public void set_font(Font fnt)
- {
- /* if they pass a null font we use the default */
- if (fnt == null) fnt = style_manager.default_font();
-
- /* if this is not a change, bail out early */
- if (fnt.equals(_font)) return;
-
- /* store the font and stash a metrics object for it */
- _font = fnt;
- _metric = manager.get_metrics(_font);
-
- damage_self();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Text to be displayed stored as a Vector of Strings */
- protected Vector _text = new Vector();
-
- /**
- * Text to be displayed stored as a Vector of Strings.
- * This should normally be treated as read-only.
- * @return Vector the array of strings that this object is displaying.
- */
- public Vector text() {return _text;}
-
- /**
- * Set text contents from a single string with lines terminated
- * by newlines or carriage returns.
- * @param String text the text to display.
- */
- public void set_text(String txt)
- {
- /* break text into lines and use that for content */
- _text = break_into_lines(txt);
-
- /* since we changed the text, refresh the screen */
- /* there is no selection */
- set_selection(NO_SELECTION, NO_SELECTION, NO_SELECTION, NO_SELECTION);
- damage_self();
- }
-
- //had:
- //* @exception bad_value if initialized with a non-string value.
-
- /**
- * Set text contents from Vector of Strings.
- * @param Vector txt the array of strings to display.
- */
- public void set_text(Vector txt)
- {
- /* convert null text to empty text */
- if (txt == null) txt = new Vector();
-
- /* first verify that the text looks ok */
- for (int i = 0; i < txt.size(); i++)
- if (!(txt.elementAt(i) instanceof String))
- throw new sub_arctic_error("Initialization with non-string in set_text()");
-
- /* if everything went well, set the text vector to a copy of the input */
- _text = (Vector)txt.clone();
-
- /* since we changed the text, refresh the screen */
- /* there is no selection */
- set_selection(NO_SELECTION, NO_SELECTION, NO_SELECTION, NO_SELECTION);
- damage_self();
- }
-
- //had:
- //* @exception bad_value if initialized with a non-string value.
-
- /**
- * Get a single string with lines terminated by the given string.
- * @param String terminator the line terminator for the return value.
- * @return String a string with the contents of this object (separated by
- * the parameter).
- */
- public String get_string(String terminator)
- {
- StringBuffer result = new StringBuffer();
-
- /* change null terminator into empty separator */
- if (terminator == null) terminator = "";
-
- /* walk over line vector concatenating each line onto result */
- for (int i = 0; i < text().size(); i++)
- {
- result.append((String)text().elementAt(i));
- result.append(terminator);
- }
-
- return result.toString();
- }
-
- /**
- * Do a human readable dump of the text and selection to System.out
- */
- public void dump_text()
- {
- int i;
- String line;
-
- /* if we have no selection, just print the lines */
- if (selection_start_line() == NO_SELECTION)
- {
- for (i = 0; i < text().size(); i++)
- System.out.println((String)text().elementAt(i));
- }
- else
- {
- /* do lines before the one where selection starts */
- for (i = 0; i < selection_start_line(); i++)
- System.out.println((String)text().elementAt(i));
-
- /* extract line with start of selection */
- line = (String)text().elementAt(i);
-
- /* print up to selection and marker for start of selection */
- System.out.print(line.substring(0,selection_start_pos()));
- System.out.print("**[");
-
- /* does the selections start and end on one line? */
- if (selection_start_line() == selection_end_line())
- {
- /* print the selected text and end marker */
- System.out.print(
- line.substring(selection_start_pos(),selection_end_pos()));
- System.out.print("]**");
-
- /* and the remainder of the line */
- System.out.println(line.substring(selection_end_pos()));
- }
- else
- {
- /* print remainder of the line */
- System.out.println(line.substring(selection_start_pos()));
-
- /* print lines that are completely selected */
- for (i = selection_start_line()+1; i < selection_end_line(); i++)
- System.out.println((String)text().elementAt(i));
-
- /* extract line selection ends on */
- line = (String)text().elementAt(selection_end_line());
-
- /* print selected text and end marker */
- System.out.print(
- line.substring(0,selection_end_pos()));
- System.out.print("]**");
-
- /* and the remainder of the line */
- System.out.println(line.substring(selection_end_pos()));
- }
-
- /* finally print all non-selected lines after the selection */
- for (i = selection_end_line()+1; i < text().size(); i++)
- System.out.println((String)text().elementAt(i));
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Convert a single string into a series of line strings stored in a
- * Vector. Lines are delimited by newlines or carriage returns.
- *
- * @param String all_text the text to break up into lines
- * @param Vector the array of lines of the broken up text
- */
- public static Vector break_into_lines(String all_text)
- {
- Vector result = new Vector();
- String rest;
- int pos, nl1, nl2, nl;
-
- /* catch null string and treat as empty */
- if (all_text == null) all_text = "";
-
- pos = 0;
- for (pos = 0; ; pos = nl+1)
- {
- /* find first line break after current position */
- nl1 = all_text.indexOf('\n',pos);
- nl2 = all_text.indexOf('\r',pos);
- if (nl1 < nl2 || nl2 == -1)
- nl = nl1;
- else
- nl = nl2;
-
- /* if there is none append any non-empty last line and we are done */
- if (nl == -1)
- {
- /* pull out the remaining substring and append it as a line */
- rest = all_text.substring(pos);
- if (rest.length() > 0)
- result.addElement(rest);
-
- /* make sure we have at least one line */
- if (result.size() == 0) result.addElement("");
-
- return result;
- }
- else
- {
- /* otherwise append that line and keep trying */
- result.addElement(all_text.substring(pos,nl));
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Constant for a special selection point used to denote that there is no
- * selection. */
- public static final int NO_SELECTION = -1;
-
- /** Constant used to denote that the selection is at the end of a line or
- * line is the last one in the text.
- */
- public static final int SELECT_END = -2;
-
- /** Start line of the current selection. */
- protected int _selection_start_line = 0;
-
- /** Start line of the current selection. */
- public int selection_start_line() {return _selection_start_line;}
-
- /** Position of start of selection within the start line. */
- protected int _selection_start_pos = 0;
-
- /** Position of start of selection within the start line. */
- protected int selection_start_pos() {return _selection_start_pos;}
-
- /** Ending line of the current selection. */
- protected int _selection_end_line = 0;
-
- /** Ending line of the current selection. */
- public int selection_end_line() {return _selection_end_line;}
-
- /** Position of end of selection within the ending line. */
- protected int _selection_end_pos = 0;
-
- /** Position of end of selection within the ending line. */
- protected int selection_end_pos() {return _selection_end_pos;}
-
- /**
- * Set the current selection. The special value NO_SELECTION can be coded
- * in any position to denote that there is no current selection (in that
- * case the other parameters are ignored). The special value SELECT_END
- * may be applied to either a line or a character position to denote the
- * last line, or the position after the last character respectively.
- *
- * @param int st_line the starting line of the new selection.
- * @param int st_pos the starting position of the new selection.
- * @param int end_line the ending line of the new selection.
- * @param int end_pos the ending position of the new selection.
- */
- public void set_selection(int st_line, int st_pos, int end_line, int end_pos)
- {
- int temp;
-
- /* if we have no selection, set that everywhere */
- if (st_line == NO_SELECTION || st_pos == NO_SELECTION ||
- end_line == NO_SELECTION || end_pos == NO_SELECTION)
- {
- st_line = st_pos = end_line = end_pos = NO_SELECTION;
- }
-
- /* replace SELECT_END special value in lines */
- if (st_line == SELECT_END) st_line = text().size()-1;
- if (end_line == SELECT_END) end_line = text().size()-1;
-
- /* force lines into valid range */
- if (st_line < 0 && st_line != NO_SELECTION) st_line = 0;
- if (end_line < 0 && end_line != NO_SELECTION) end_line = 0;
- if (st_line > text().size()-1) st_line = text().size()-1;
- if (end_line > text().size()-1) end_line = text().size()-1;
-
- /* replace SELECT_END special value in positions */
- if (st_pos == SELECT_END)
- st_pos = ((String)text().elementAt(st_line)).length();
- if (end_pos == SELECT_END)
- end_pos = ((String)text().elementAt(end_line)).length();
-
- /* force positions into range */
- if (st_pos < 0 && st_pos != NO_SELECTION) st_pos = 0;
- if (end_pos < 0 && end_pos != NO_SELECTION) end_pos = 0;
- if (st_line != NO_SELECTION &&
- st_pos > ((String)text().elementAt(st_line)).length())
- st_pos = ((String)text().elementAt(st_line)).length();
- if (end_line != NO_SELECTION &&
- end_pos > ((String)text().elementAt(end_line)).length())
- end_pos = ((String)text().elementAt(end_line)).length();
-
- /* make sure we are ordered properly */
- if (end_line < st_line ||
- (end_line == st_line && end_pos < st_pos))
- {
- temp = end_line;
- end_line = st_line;
- st_line = temp;
- temp = end_pos;
- end_pos = st_pos;
- st_pos = temp;
- }
-
- /* if this is a change, do the assignment and ask for redraw */
- if (end_line != _selection_end_line || end_pos != _selection_end_pos ||
- st_line != _selection_start_line || st_pos != _selection_start_pos)
- {
- _selection_end_line = end_line;
- _selection_end_pos = end_pos;
- _selection_start_line = st_line;
- _selection_start_pos = st_pos;
- damage_self();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Constant used to store boxed flag within interactor flags */
- public static final int BOXED = FIRST_FREE_FLAG;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Does the interactor have a box drawn around it.
- * @return boolean true if this interactor is boxed.
- */
-
- public boolean boxed()
- {
- return flag_is_set(BOXED);
- }
-
- /**
- * Set the flag indicating whether interactor is drawn with a surrounding
- * box.
- * @param boolean box true if this interactor is boxed.
- */
- public void set_boxed(boolean bxv)
- {
- /* if we have a change, set the bit and ask for redraw */
- if (bxv != boxed())
- {
- set_flag_bit(BOXED, bxv);
- damage_self();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Compute a size based on current content.
- */
- public void size_by_content()
- {
- int hv, wv, max_w, i;
-
- /* compute the height */
- hv = _metric.getHeight() * text().size() + 2*v_spacing();
-
- /* find the max width */
- max_w = 0;
- for (i = 0; i < text().size(); i++)
- {
- /* measure the line and see if its biggest so far */
- wv = _metric.stringWidth((String)text().elementAt(i));
- if (wv > max_w) max_w = wv;
- }
-
- /* add in the border */
- max_w += 2*h_spacing();
-
- /* if this is a change, set the size */
- if (h() != hv || w() != max_w)
- set_size(max_w, hv);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Parts that we intrinsically constrain. Here we modify what our
- * super types result by removing part_a from the set.
- * @return int a bitset indicating all parts that are intrinsically
- * constrained.
- */
- public int intrinsic_constraints()
- {
- return super.intrinsic_constraints() & ~PART_A;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Return the value of the part_a component of this object. In our case
- * this is stored in _first_line.
- * @return int the value of part_a (AKA first_line).
- */
- public int part_a()
- {
- /* Make sure its up to date and in range then return it */
- eval_part_a();
- return _first_line;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Set part_a value directly bypassing the constraint system (but doing
- * damage). This should normally only be done by the constraint system
- * or some other part of the system which takes care of marking things
- * out-of-date, etc. itself. In this case part_a is stored in _first_line.
- *
- * @param int v the new value.
- */
- protected void set_raw_part_a(int v)
- {
- /* don't do anything unless this is a change */
- if (v != _first_line)
- {
- /* make change and do damage */
- _first_line = v;
- damage_self();
- }
- }
-
- //had:
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Set the part_a component of this object. In our case this is stored in
- * _first_line.
- *
- * @param int v the new value
- */
- public void set_part_a(int v)
- {
- /* if this has a constraint throw an exception */
- if ((active_constraints() & PART_A) != 0)
- throw new sub_arctic_error(
- "Attempt to assign value to constrained part_a " +
- "(AKA text_display.first_line)");
-
- /* don't do anything unless this is a change */
- if (v != _first_line)
- {
- set_raw_part_a(v);
- mark_part_a_ood();
- }
- }
-
- //had:
- //* @exception cannot_assign if the value is constrained.
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * First line to display. This is tied to part_a of this object so it
- * can be constrained and/or exported to constraint. If this is negative,
- * we still display the 0th line at the top and if this goes past the end
- * we display nothing.
- */
- protected int _first_line = 0;
-
- /**
- * First line to display. This is tied to part_a of this object so it
- * can be constrained and/or exported to constraint. If this is negative,
- * we still display the 0th line at the top and if this goes past the end
- * we display nothing.
- *
- * @return int the first line offset.
- */
- public int first_line() {return part_a();}
-
- /**
- * Set the first line to display. This is tied to part_a of this object so it
- * can be constrained and/or exported to constraint. If this is negative,
- * we still display the 0th line at the top and if this goes past the end
- * we display nothing.
- *
- * @param int frst_ln the first line to display.
- */
- public void first_line(int frst_ln)
- {
- set_part_a(frst_ln);
- }
-
- //had:
- //* @exception cannot assign if part_a has a constraint attached.
- //* @exception general
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Full constructor with explicit size. Text contents is provided by
- * one string with lines separated by newlines or carriage returns.
- * @param int xv x position of this interactor.
- * @param int yv y position of this interactor.
- * @param int wv width of this interactor.
- * @param int hv height of this interactor.
- * @param String contents the text to display in this box.
- * @param Font fnt the font to use for drawing these strings.
- * @param boolean boxed true if this object should have a box around it.
- */
- public text_display(
- int xv, int yv, int wv, int hv,
- String contents,
- Font fnt,
- boolean boxed)
- {
- super(xv,yv,wv,hv);
- set_font(fnt);
- set_text(contents);
- set_boxed(boxed);
- set_selection(NO_SELECTION,0,0,0);
- }
-
- //had:
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Full constructor with size determined by initial text. Text contents
- * is provided by one string with lines separated by newlines or carriage
- * returns.
- *
- * @param int xv x position of this interactor.
- * @param int yv y position of this interactor.
- * @param String contents the text to display in this box.
- * @param Font fnt the font to use for drawing these strings.
- * @param boolean boxed true if this object should have a box around it.
- */
- public text_display(
- int xv, int yv,
- String contents,
- Font fnt,
- boolean boxed)
- {
- super(xv,yv);
-
- /* set the instance vars */
- set_font(fnt);
- set_text(contents);
- set_boxed(boxed);
- set_selection(NO_SELECTION,0,0,0);
-
- /* compute a size based on the content */
- size_by_content();
- }
-
- //had:
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Constructor with computed size, default font, and default
- * boxed status.
- *
- * @param int xv x position of this interactor.
- * @param int yv y position of this interactor.
- * @param String contents the text to display in this box.
- */
- public text_display(int xv, int yv, String contents)
- {
- this(xv,yv,contents, null, false);
- }
-
- //had:
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** X position of current line. This is used internally only during
- * drawing.
- */
- protected static int xpos = 0;
-
- /** Y position of current line . This is used internally only during
- * drawing.
- */
- protected static int ypos = 0;
-
- /** Max Y position we need to do text drawing at (taking into account the
- * ascent of the font). Any line of text whose baseline is past this
- * value will not show up and doesn't need to be drawn. This is used
- * internally only during drawing and is normally set to the height of
- * the area plus the ascent of the font.
- */
- protected static int ypos_cutoff = 0;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw a series of lines of unhighlighted text. The static variables
- * xpos and ypos are used here to keep track of current line position and
- * communicate that between subsequent calls. We assume here that the
- * background has been cleared, the font has been set and that the current
- * color is set right for drawing text.
- *
- * @param drawable d the surface to do the drawing on.
- * @param int st_ln starting line.
- * @param int end_ln ending line.
- */
- protected void draw_norm_lines(drawable d, int st_ln, int end_ln)
- {
- /* if we are already past the bottom bail out early. */
- if (ypos > ypos_cutoff) return;
-
- /* start at beginning of line */
- xpos = h_spacing();
- for (int i = st_ln; i <= end_ln; i++)
- {
- /* draw only once we get to the first line */
- if (i >= first_line())
- {
- d.drawString((String)text().elementAt(i), xpos, ypos);
- ypos += _metric.getHeight();
- }
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw line that is partially highlighted. The highlight runs from the
- * given starting position to the given ending position (or SELECT_END
- * if the highlight goes past end of line). The static variables xpos and
- * ypos are used here to keep track of current line position and
- * communicate that between subsequent calls. We assume here that the
- * background has been cleared and the font set.
- *
- * @param drawable d the surface to do the drawing on.
- * @param int ln_num the line number of the split line.
- * @param int st_pos the position in the line of the start of the
- * split.
- * @param int end_pos the position in the line of the end of the split.
- */
- protected void draw_split_line(
- drawable d,
- int ln_num,
- int st_pos,
- int end_pos)
- {
- String line, part;
- int endx;
-
- /* if we are past the end or haven't gotten to the beginning bail now. */
- if (ypos > ypos_cutoff || ln_num < first_line()) return;
-
- /* start at beginning of line */
- xpos = h_spacing();
-
- /* draw unhighlighted part of line */
- line = (String)text().elementAt(ln_num);
-
- /* if we have an unhighlighted leading part, draw that */
- if (st_pos > 0)
- {
- part = line.substring(0,st_pos);
- d.drawString(part, xpos, ypos);
- xpos += _metric.stringWidth(part);
- }
-
- /* if highlight is past end stop at w() otherwise calculate stop point */
- if (end_pos == SELECT_END)
- {
- part = line.substring(st_pos);
- endx = w();
- }
- else
- {
- part = line.substring(st_pos,end_pos);
- endx = xpos + _metric.stringWidth(part);
- }
-
- /* draw highlight rect from 1/2 leading above to 1/2 leading below */
- d.setColor(Color.black);
- d.fillRect(xpos, ypos -_metric.getAscent()-(_metric.getLeading()/2),
- endx-xpos, _metric.getHeight());
-
- /* now draw text over that in white */
- d.setColor(Color.white);
- d.drawString(part, xpos,ypos);
- xpos = endx;
-
- /* finally draw non-highlighted tail (if any) */
- if (end_pos != SELECT_END)
- {
- part = line.substring(end_pos);
- d.setColor(Color.black);
- d.drawString(part, xpos,ypos);
- }
-
- /* set up for the next line */
- ypos += _metric.getHeight();
- xpos = h_spacing();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw a series of fully highlighted lines. The static variables xpos and
- * ypos are used here to keep track of current line position and
- * communicate that between subsequent calls. We assume here that the
- * background has been cleared and the font set.
- *
- * @param drawable d the surface to do the drawing on.
- * @param int first_ln the line number of the first highlighted line.
- * @param int last_ln the line number of the last highlighted line.
- */
- protected void draw_highlighted_lines(drawable d, int first_ln, int last_ln)
- {
- int num = last_ln - Math.max(first_ln, first_line()) + 1;
-
- /* if we have no lines or we are past the end bail now */
- if (num <= 0 || ypos > ypos_cutoff) return;
-
- /* draw the background highlight */
- d.setColor(Color.black);
- d.fillRect(xpos, ypos - _metric.getAscent() - (_metric.getLeading()/2),
- w(), num*_metric.getHeight());
-
- /* draw the text over the top in white */
- d.setColor(Color.white);
- for (int i = first_ln; i <= last_ln; i++)
- {
- /* draw only if we have made it to at least the first line */
- if (i >= first_line())
- {
- d.drawString((String)text().elementAt(i), xpos, ypos);
- ypos += _metric.getHeight();
- }
- }
-
- /* reset the color for the next guy */
- d.setColor(Color.black);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw image of text with selection and optional box
- * @param drawable d the drawable to work on
- */
- protected void draw_self_local(drawable d)
- {
- String line;
- int xloc, sel_y;
- style cs=style_manager.current_style();
- int dvs=cs.drawable_vertical_space(),
- dhs=cs.drawable_horizontal_space();
-
- /* enough space for the snazzy style stuff? */
- if ((v_spacing()>=dvs) &&
- (h_spacing()>=dhs)) {
- /* there is enough */
- cs.drawable_prepare_rect(d,0,0,w(),h(),false, true);
- /* use the default system background color for text */
- d.setColor(style_manager.default_color_scheme().text_background());
- /* fill in the rect, but be sure to not go over the beveling */
- d.fillRect(dhs,dvs,w()-(2*dhs),h()-(2*dvs));
- } else {
- /* clear the rectangle behind us */
- d.setColor(style_manager.default_color_scheme().text_background());
- d.fillRect(0,0,w()-1,h()-1);
- }
-
- /* set font to our font, and start drawing in foreground */
- d.setFont(font());
- d.setColor(style_manager.default_color_scheme().foreground());
-
- /* establish the bottom cutoff value to end drawing text */
- ypos_cutoff = h() + _metric.getAscent();
-
- /* set the initial drawing position */
- xpos = h_spacing();
- ypos = v_spacing() + _metric.getAscent();
-
- /* if we have no selection, just draw the text */
- if (selection_start_line() == NO_SELECTION)
- {
- draw_norm_lines(d, 0, text().size()-1);
- }
- /* if we have point selection draw normal text then an insert line */
- else if (selection_start_line() == selection_end_line() &&
- selection_start_pos() == selection_end_pos())
- {
- draw_norm_lines(d, 0, text().size()-1);
- line = (String)text().elementAt(selection_start_line());
- xloc = _metric.stringWidth(line.substring(0,selection_start_pos()));
- sel_y = v_spacing()+
- (selection_start_line() - first_line())*_metric.getHeight();
- d.drawLine(xloc + h_spacing(),sel_y,
- xloc + h_spacing(), sel_y + _metric.getHeight());
- }
- else
- {
- /* draw normal lines up to line with selection */
- draw_norm_lines(d, 0, selection_start_line()-1);
-
- /* draw highlight */
-
- /* is selection all on one line? */
- if (selection_start_line() == selection_end_line())
- {
- /* just draw the highlight all on one line */
- draw_split_line(d, selection_start_line(),
- selection_start_pos(), selection_end_pos());
- }
- else
- {
- /* draw line with highlight from start to end of line */
- draw_split_line(d, selection_start_line(),
- selection_start_pos(), SELECT_END);
-
- /* draw fully highlighted lines */
- draw_highlighted_lines(d, selection_start_line()+1,
- selection_end_line()-1);
-
- /* draw rest of highlight on the last line */
- draw_split_line(d, selection_end_line(), 0,selection_end_pos());
- }
-
- /* draw normal lines after highlight */
- draw_norm_lines(d, selection_end_line()+1, text().size()-1);
-
- }
-
- /* draw the border rect if needed */
- if (boxed())
- {
- d.setColor(Color.black);
- d.drawRect(0,0,w()-1,h()-1);
- }
- }
-
- //had:
- //* @exception general PROPAGATED
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- };
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-